import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
// import ReportFormProductionStatistics from '@main/entities/service/admin/reportForm/report-form-period-status-monitoring.entity';
import { Repository, Between, In, Like } from 'typeorm';
import BaseMachine from '@main/entities/service/admin/base/base-machine.entity';
import WipOrderReport from '@main/entities/service/admin/wip/wip-order-report.entity';
import ProductionOrder from '@main/entities/service/admin/production/production-order.entity';
import { ApiException } from '@main/common/exceptions/api.exception';
import { generateExcelFn } from '@main/excel';
import { format } from 'date-fns';

@Injectable()
export class ReportFormProductionStatisticsService {
  constructor(
    @InjectRepository(BaseMachine)
    private machineRepository: Repository<BaseMachine>,
    // @InjectRepository(ReportFormProductionStatistics)
    // private reportFormProductionStatisticsRepository: Repository<ReportFormProductionStatistics>,
    @InjectRepository(WipOrderReport)
    private orderReportRepository: Repository<WipOrderReport>,
    @InjectRepository(ProductionOrder)
    private orderRepository: Repository<ProductionOrder>
  ) {}

  /**
   * 罗列所有配置
   */
  async page(data) {
    const { pageSize, pageNum, entity = {} } = data;

    const { machineCodeList, actualCompleteDate, fastSearch, ids = [] } = entity;

    const where: any[] = []; // 初始化为数组以便后续拼接

    // 处理 userIdList 进行匹配
    if (actualCompleteDate && actualCompleteDate.length) {
      if (machineCodeList && machineCodeList.length) {
        if (fastSearch) {
          where.push({
            orderStatusCode: '40',
            machineCode: In(machineCodeList),
            updateTime: Between(new Date(actualCompleteDate[0]), new Date(actualCompleteDate[1])),
            materialName: Like(`%${fastSearch}%`),
            materialCode: Like(`%${fastSearch}%`),
          });
        } else {
          where.push({
            orderStatusCode: '40',
            machineCode: In(machineCodeList),
            updateTime: Between(new Date(actualCompleteDate[0]), new Date(actualCompleteDate[1])),
          });
        }
      } else if (fastSearch) {
        where.push(
          {
            orderStatusCode: '40',
            materialCode: Like(`%${fastSearch}%`),
            updateTime: Between(new Date(actualCompleteDate[0]), new Date(actualCompleteDate[1])),
          },
          {
            orderStatusCode: '40',
            materialName: Like(`%${fastSearch}%`),
            updateTime: Between(new Date(actualCompleteDate[0]), new Date(actualCompleteDate[1])),
          }
        );
      } else {
        where.push({
          orderStatusCode: '40',
          updateTime: Between(new Date(actualCompleteDate[0]), new Date(actualCompleteDate[1])),
        });
      }
    }

    if (ids && ids.length) {
      for (const item of where) {
        item['id'] = In(ids);
      }
    }

    const [orderList, total]: any = await this.orderRepository.findAndCount({
      where,
      order: {
        updateTime: 'DESC',
      },
      take: pageSize,
      skip: (pageNum - 1) * pageSize,
    });

    await Promise.all(
      orderList.map(async (item) => {
        const { orderCode, machineCode, materialLength, materialWidth, materialHeight } = item;

        const orderReportList = await this.orderReportRepository.find({
          where: {
            orderCode,
            machineCode,
            reportFinishStatus: 1,
          },
          order: { updateTime: 'DESC' },
        });

        let allReportNum = 0;

        let allGoodNum = 0;

        let allBadNum = 0;

        for (const mItem of orderReportList) {
          const { reportStatus, reportConfirmNum, reportNum, badNum, goodNum, reportTime } = mItem;

          if (reportStatus === 1) {
            allReportNum += reportConfirmNum;
          } else {
            allReportNum += reportNum;
          }

          allGoodNum += goodNum;

          allBadNum += badNum;

          if (reportTime) {
            item.actualCompleteTime = format(new Date(reportTime), 'yyyy-MM-dd');
          }
        }

        const obj = await this.machineRepository.findOne({ where: { machineCode } });

        item.machineName = obj.machineName || '-';

        item.materialStandards = `${materialLength}*${materialWidth}*${materialHeight}`;

        item.completeNum = allReportNum;

        item.goodNum = allGoodNum;

        item.badNum = allBadNum;

        let yieldRate = (allGoodNum / allReportNum) * 100;

        item.yieldRate = isNaN(yieldRate) ? 0 : yieldRate.toFixed(2);
      })
    );

    return [orderList, total];
  }

  async export(dto, lang) {
    const [list] = await this.page(dto);

    if (!list || !(list as any).length) {
      throw new ApiException(10052);
    }

    const dataList = list;

    return await generateExcelFn(
      {
        sheetName: 'productionStatistics',
        mainHeaderList: [
          {
            label: 'machineCode',
          },
          {
            label: 'machineName',
          },
          {
            label: 'materialCode',
          },
          {
            label: 'materialName',
          },
          {
            label: 'materialStandards',
          },
          {
            label: 'actualCompleteDate',
            prop: 'actualCompleteTime',
          },
          {
            label: 'completeNum',
          },
          {
            label: 'goodNum',
          },
          {
            label: 'badNum',
          },
          {
            label: 'yieldRate',
          },
        ],
        dataList,
      },
      lang
    );
  }
}
